package com.teamone.etl.datasource.service.impl;

import com.teamone.etl.datasource.pool.JdbcConnector;
import com.teamone.etl.datasource.service.DataSourceFeignService;
import com.teamone.etl.exception.CommonCode;
import com.teamone.etl.exception.CustomException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 @author WangZhuoRan */
@Service
@Transactional(rollbackFor = Exception.class)
public class DataSourceFeignServiceImpl implements DataSourceFeignService {

    @Override
    public List<String> getAllDataBaseByDataSourceId (Integer id) throws CustomException {
        List<String> databases = new ArrayList<>();
        final PreparedStatement[] ps = {null};
        final ResultSet[] rs = {null};
        try {
            Connection connection = JdbcConnector.JDBC_POOL_MAP.get(id);
            ps[0] = connection.prepareStatement("show DATABASES");
            rs[0] = ps[0].executeQuery();
            while (rs[0].next()) {
                databases.add(rs[0].getString(1));
            }
        } catch (SQLException throwables) {
            throw new CustomException(CommonCode.CONNECTION_FAIL);
        }
        System.out.println(databases);
        return databases;
    }

    @Override
    public List<String> getAllTableByDataBaseName (Integer id, String dataBaseName) throws CustomException {
        List<String> table = new ArrayList<>();
        final PreparedStatement[] ps = {null};
        final ResultSet[] rs = {null};
        try {
            Connection connection = JdbcConnector.JDBC_POOL_MAP.get(id);
            ps[0] = connection.prepareStatement("SHOW TABLES FROM "+dataBaseName);
            rs[0] = ps[0].executeQuery();
            while (rs[0].next()) {
                table.add(rs[0].getString(1));
            }
        } catch (SQLException throwables) {
            throw new CustomException(CommonCode.CONNECTION_FAIL);
        }
        System.out.println(table);
        return table;
    }

    @Override
    public Map<String, List<String>> getAllColumnByTableName (Integer id,String tableName,String dataBaseName) throws CustomException {
        List<String> column = new ArrayList<>();
        List<String> columnType = new ArrayList<>();
        List<String> columnComment = new ArrayList<>();
        List<String> columnTypeLength = new ArrayList<>();
        List<String> columnIsNullable = new ArrayList<>();
        Map<String, List<String>> columnMap = new ConcurrentHashMap<>(16);
        final PreparedStatement[] ps = {null};
        final ResultSet[] rs = {null};
        try {
            Connection connection = JdbcConnector.JDBC_POOL_MAP.get(id);
            ps[0] = connection.prepareStatement("SELECT column_name,data_type,column_comment," +
                    "character_maximum_length,is_nullable FROM information_schema.columns " +
                    "WHERE table_name = '" + tableName + "' AND table_schema = '" + dataBaseName + "'");
            rs[0] = ps[0].executeQuery();
            while (rs[0].next()) {
                column.add(rs[0].getString(1));
                columnType.add(rs[0].getString(2));
                columnComment.add(rs[0].getString(3));
                columnTypeLength.add(rs[0].getString(4));
                columnIsNullable.add(rs[0].getString(5));
            }
            columnMap.put("column", column);
            columnMap.put("columnType", columnType);
            columnMap.put("columnComment", columnComment);
            columnMap.put("columnTypeLength", columnTypeLength);
            columnMap.put("columnIsNullable", columnIsNullable);
        } catch (SQLException throwables) {
            throw new CustomException(CommonCode.CONNECTION_FAIL);
        }
        return columnMap;
    }

}
